package com.hins.demo.transfer.executor;

import com.hins.component.dto.Response;
import com.hins.demo.ability.AccountTransferService;
import com.hins.demo.common.event.DomainEventPublisher;
import com.hins.demo.dto.TransferUpdateCmd;
import com.hins.demo.dto.event.TransferEvent;
import com.hins.demo.gateway.ExchangeRateGateway;
import com.hins.demo.gateway.TransferGateway;
import com.hins.demo.model.transfer.entity.Account;
import com.hins.demo.model.transfer.valueobject.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

/**
 * Description: 转账
 *
 * @author wenjiaqi
 * @date 2021/5/14 15:23
 */
@Component
public class TransferUpdateCmdExe {
    @Autowired
    private TransferGateway transferGateway;

    @Autowired
    private ExchangeRateGateway exchangeRateGateway;

    @Autowired
    private AccountTransferService accountTransferService;

    @Autowired
    private DomainEventPublisher domainEventPublisher;

    public Response execute(TransferUpdateCmd cmd) {

        // 参数校验
        Money targetMoney = new Money(cmd.getTransferDTO().getAmount(), new Currency(cmd.getTransferDTO().getCurrency()));

        // 读数据，参数校验
        Account sourceAccount = transferGateway.find(new UserId(cmd.getTransferDTO().getSourceUserId()));
        Account targetAccount = transferGateway.find(new AccountNumber(cmd.getTransferDTO().getTargetAccountNumber()));

        // 反腐网关取出汇率
        ExchangeRate exchangeRate = exchangeRateGateway.getExchangeRate(sourceAccount.getCurrency(), targetMoney.getCurrency());

        // 业务逻辑，领域服务，这里对entity的操作，并对以后的变化影响也在这里面
        accountTransferService.transfer(sourceAccount, targetAccount, targetMoney, exchangeRate);

        // 保存数据
        transferGateway.save(sourceAccount);
        transferGateway.save(targetAccount);

        // 发送转账消息
        domainEventPublisher.publish(new TransferEvent());

        return Response.buildSuccess();
    }
}
